package uml.behavioral.interpreter;

import uml.behavioral.interpreter.*;
import uml.behavioral.interpreter.exception.IllegalInstructionException;

import java.util.Stack;

/**
 * 解释器--指令解析与解释<br>
 * on 2022/12/31 0:25
 */
public class InstructionInterpreter{
    /**
     * 句子
     */
    private String instuction;
    /**
     * 抽象语法树
     */
    private AbstractNode node;

    /**
     * 根据文法规则对语句指令进行解析,生成语法树实例,文法规则如下：<br>
     * expression ::= direction action distance unit | composite<br>
     * composite ::= expression then expression<br>
     * direction ::=up | down| left | right<br>
     * action ::=move | run | roll | walk | slip | jump | climb<br>
     * distance ::= an number<br>
     * unit ::=cm | dm | m | km<br>
     * @param instruction 应为一条符合文法规则的语句
     * @throws IllegalInstructionException 指令不符合文法规则时
     */
    public void parse(String instruction) throws IllegalInstructionException {
        this.instuction = instruction;
        AbstractNode left = null, right = null, direction = null, action = null, distance = null, unit = null;
        Stack<AbstractNode> stack = new Stack<>();
        String[] words = instruction.split(" ");
        for (int i = 0; i < words.length; i++) {
            try {
                if (words[i].equalsIgnoreCase("then")) {
                    left = stack.pop();
                    String w1 = words[++i];
                    DirectionNode directionNode = new DirectionNode(w1);
                    String w2 = words[++i];
                    ActionNode actionNode = new ActionNode(w2);
                    String w3 = words[++i];
                    DistanceNode distanceNode = new DistanceNode(w3);
                    String w4 = words[++i];
                    UnitNode unitNode = new UnitNode(w4);
                    right = new SentenceNode(directionNode, actionNode, distanceNode, unitNode);
                    stack.push(new AndNode(left, right));
                } else {
                    String w1 = words[i];
                    DirectionNode directionNode = new DirectionNode(w1);
                    String w2 = words[++i];
                    ActionNode actionNode = new ActionNode(w2);
                    String w3 = words[++i];
                    DistanceNode distanceNode = new DistanceNode(w3);
                    String w4 = words[++i];
                    UnitNode unitNode = new UnitNode(w4);
                    left = new SentenceNode(directionNode, actionNode, distanceNode, unitNode);
                    stack.push(left);
                }
            } catch (Exception e) {
               throw new IllegalInstructionException("指令 '"+this.instuction+"' 未正确结束:"+i);
            }
        }
        this.node = stack.pop();
    }

    /**
     * 根据文法规则对语法树实例进行解释
     * @return 语法树的解释
     * @throws IllegalInstructionException 语法树实例解释异常时
     */
    public String interpret() throws IllegalInstructionException {
        String interpretResult = node.interpret();
        return interpretResult;
    }
}
